package dominio.neuronio.especializacao;

import java.text.DecimalFormat;

import dominio.ativacao.FuncaoAtivacao;
import dominio.ativacao.especializacao.FuncaoDegrau;
import dominio.neuronio.NeuronioAbstrato;
import dominio.neuronio.Sinapse;
import dominio.padrao.Padrao;
import excessao.ExcessiveInputsException;

/**
 * @author Paulo Vitor
 * @author Roberto Su
 * 
 * @description
 *
 *
 */
public class NeuronioMcCullochPitts extends NeuronioAbstrato {
	
	/**
	 * 
	 */
	public NeuronioMcCullochPitts(){
		super();
	}

	/**
	 * 
	 * @param funcaoAtivacao
	 */
	private NeuronioMcCullochPitts(FuncaoAtivacao funcaoAtivacao) {
		super(funcaoAtivacao);
	}
	
	/**
	 * 
	 * @param theta
	 */
	public NeuronioMcCullochPitts( double theta ){
		this( new FuncaoDegrau( theta ) );
	}

	/*
	 * (non-Javadoc)
	 * @see dominio.neuronio.Neuronio#estimular(double[])
	 */
	public double estimular(Padrao padrao) throws ExcessiveInputsException {

		// gera as sinapses à partir das entradas
		if( padrao.getQtdeEstimulos() > 2 ){
			throw new ExcessiveInputsException("O neuronio de McCulloch Pitts não pode receber mais de duas entradas!");
		}
		
		this.criarSinapses( padrao, new double[]{1,1} );
		
		// processa a soma das saídas das sinapses
		this.entradaLiquida = this.totalizarEntradaLiquida();

		// aplica a função de ativação
		this.saida = this.funcaoAtivacao.aplicarFuncaoAtivacao( this.entradaLiquida );

		// retorna y
		return this.saida;
	}
	
	/*
	 * (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		DecimalFormat formatter = new DecimalFormat( "0.0000" );
		formatter.setPositivePrefix( " " );

		StringBuffer buf = new StringBuffer();
		buf.append( "# Neuronio McCulloch Pitts\n" );

		// sinapses
		buf.append( "\tSinapses: \n" );
		if ( this.sinapses != null && this.sinapses.size() > 0 ) {
			for( Sinapse sinapse : this.sinapses ) {
				buf.append( "\t\t" ).append( sinapse.toString(true) ).append( "\n" );
			}
		}

		// entrada líquida
		buf.append( "\n\tEntrada liquida: " ).append( formatter.format( this.entradaLiquida ) ).append( "\n" );

		// função de ativação
		buf.append( "\tFuncao de ativacao: " );
		buf.append( this.funcaoAtivacao != null ? this.funcaoAtivacao.toString() : null ).append( "\n" );

		// saida
		buf.append( "\tSaida: " ).append( formatter.format( this.saida ) ).append( "\n\n" );

		return buf.toString();
	}

}
